import qs from 'qs'
import {deepClone} from './index'
// 缓存对象
const cache = {
  // 缓存列表
  list: [],
  // 最大缓存数
  MAX_NUM: 100,
  // 最大缓存时间
  EXPIRED_TIME: 5 * 1000,
  // 根据请求的信息(请求方式,url,请求get/post数据),产生map的key
  getRequestKey(config){
      const { method, url, params, data } = config;
      return [method, url, qs.stringify(params), qs.stringify(data)].join("&");
  },
  // 添加缓存结果
  add({config, data}){
      data = deepClone(data)
      if(config.data) config.data = JSON.parse(config.data)
      let key = this.getRequestKey(config)
      let i = this.list.findIndex(t=>t.key === key)
      if(i>-1){
          // 保存请求结果
          this.list[i].data = data
          // 把结果给接口
          this.list[i].resolve(data)
      }else{
          // 添加到缓存列表中
          this.list.push({ time: Date.now(), key, data })
      }
  },
  // 查找缓存结果
  find(config){
      // 根据请求信息生成key
      let key = this.getRequestKey(config)
      let i = this.list.findIndex(t=>  t.key === key)
      // 判断缓存当中是否有该请求结果
      if(i>-1){
          let f = this.list[i]
          // 判断是否超出了最大缓存时间
          if(Date.now() - f.time > this.EXPIRED_TIME){
              // 清除该缓存
              this.list.splice(i, 1)
          }else{
              // 返回缓存
              return f
          }
      }
      // 添加缓存信息
      let t = {key, time: Date.now()}
      t.data = new Promise((resolve)=>{
          t.resolve = resolve
      })
      // 判断是否超出了最大缓存数量
      if(this.list.length === this.MAX_NUM){
          this.list.shift()
      }
      this.list.push(t)
      // 返回undefined,让请求拦截不执行config.adapter
      return undefined
  }
}
export default cache

export async function interceptorsRequest(config){
  let f = cache.find(config);
  // 查看缓存当中有没有
  if (f) {
    // 通过config.adapter,允许自定义处理请求
    config.adapter = function (config) {
      return new Promise((resolve) => {
        const res = {
          status: 200,
          statusText: "OK",
          headers: { "content-type": "application/json; charset=utf-8" },
          config,
          request: {},
        };
        // 判断缓存当中data是否是Promise?
        //   如果是,代表数据正在获取中
        //   如果不是代表请求已经获取过
        if (f.data instanceof Promise) {
          f.data.then((data) => {
            resolve({ ...res, data });
          });
        } else {
          resolve({ ...res, data: f.data });
        }
      });
    };
  }
  return config;
}
